<template>
	<!-- 聊天消息容器 -->
	<view class="chat-container">
		<!-- 可滚动消息列表 -->
		<scroll-view class="message-list" scroll-y :scroll-into-view="getLastMessageId()" scroll-with-animation>
			<!-- 遍历消息数组，显示每一条消息 -->
			<view v-for="(msg, index) in messages" :id="'msg-' + index" :key="index" class="message-bubble"
				:class="msg.role">
				<view class="message-item" v-if="msg.role == 'assistant' || msg.role == 'user'">
					<!-- 如果消息角色为助手，则显示头像 -->
					<view v-if="msg.role === 'assistant'" class="assistant-avatar">
						<image src="@/static/img/last-wel.gif" class="jz-logo" mode="aspectFill" />
						<!-- 只有在没有思考状态且没有内容时才显示头像旁的加载图标 -->
						<view
							v-if="isLoading && !msg.thinking && !msg?.reasoning_content?.length > 0 && !msg?.content?.length > 0 && !msg?.tool_calls?.length > 0"
							class="left-icon">
							<icon class="spinner-cycle iconfont bs-loading" @click="reSend(index)"></icon>
						</view>
					</view>
					<!-- 消息内容区域 -->
					<view class="message-content">
						<view class="message-root">
							<!-- 显示思考状态 -->
							<view class="thinking-status" v-if="msg.thinking && msg.thinking_text">
								<icon class="spinner-cycle iconfont bs-loading"></icon>
								<text>{{ msg.thinking_text }}</text>
								<view class="thinking-fade"></view>
							</view>

							<view class="reasoning_content" v-if="msg?.reasoning_content">
								<view class="left">&nbsp;</view>
								<ua-markdown :source="removeLeadingNewline(msg?.reasoning_content)" />
							</view>

							<!-- 显示内容，只有当有内容时才显示 -->
							<ua-markdown class="content" :class="{ 'ass': msg?.role === 'assistant' }" v-if="msg?.content"
								:source="removeLeadingNewline(msg?.content)" />

							<!-- 工具调用卡片 -->
							<view v-if="msg.tool_calls && msg.tool_calls.length > 0" class="tool-calls">
								<view v-for="(tool, tIndex) in msg.tool_calls" :key="tIndex" class="tool-card">
									<view class="tool-header">
										<icon class="iconfont bs-tool"></icon>
										<text class="tool-name">执行tools：{{ tool.function.name }}</text>
									</view>
									<view class="tool-args" v-if="formatArgs(tool.function.arguments)">
										<text class="args-text">{{ formatArgs(tool.function.arguments) }}</text>
									</view>
								</view>
							</view>
						</view>

						<!-- 底部工具按钮 -->
						<view v-if="msg.role === 'assistant' && !isLoading && !msg.thinking && msg?.content"
							class="bottom-but">
							<icon v-if="msg?.content != '请求已取消'" class="iconfont bs-copy" @click="copy(msg?.content)">
							</icon>
							<icon class="iconfont bs-reload" @click="reSend(index)"></icon>
						</view>
					</view>
				</view>
			</view>
		</scroll-view>
	</view>
</template>

<script lang="ts" setup>
/**
* 组件属性定义：
*  - messages：聊天消息数组，必填
*/
import { defineProps, defineEmits } from 'vue';
import { storeToRefs } from 'pinia';
import ThemeColorUtil from "@/jzutils/ThemeColorUtil";
import ThemeLangUtil from "@/jzutils/ThemeLangUtil";

const themeStore = ThemeColorUtil.useThemeStore();
const langStore = ThemeLangUtil.useLangStore();
const { themeData } = storeToRefs(themeStore);
const { langData } = storeToRefs(langStore);
const emit = defineEmits(['reSend']);
const props = defineProps({
	messages: {
		type: Array,
		required: true
	},
	isLoading: {
		type: Boolean,
		required: true
	},
});

/**
 * 获取最后一条消息的 DOM id，用于滚动定位
 * @returns {string} 最后一条消息的 id，如 'msg-3'
 */
function getLastMessageId(): string {
	return 'msg-' + (props.messages.length - 1);
}

/**
 * 去除消息内容开头的换行符，确保消息展示更美观
 * @param {string} content 消息文本内容
 * @returns {string} 处理后的消息文本
 */
function removeLeadingNewline(content: string): string {
	return content.replace(/^\n+/, '');
}

/**
 * 复制消息内容
 */
function copy(e) {
	uni.setClipboardData({
		data: e,
		success() {
			uni.showToast({
				title: '复制成功',
				icon: 'none'
			});
		}
	});
}

/**
 * 重新发送消息
 */
function reSend(index) {
	// 向前遍历查找最近的用户消息
	let targetIndex = -1;
	for (let i = index - 1; i >= 0; i--) {
		if (props.messages[i]?.role === 'user') {
			targetIndex = i;
			break;
		}
	}
	if (targetIndex !== -1) {
		const userContent = props.messages[targetIndex].content;
		emit('reSend', userContent, targetIndex);
	}
}

/**
 * 格式化函数参数显示
 * @param {string} args 函数参数JSON字符串
 * @returns {string} 格式化后的参数字符串
 */
function formatArgs(args: string): string {
	try {
		const parsed = JSON.parse(args);
		return Object.entries(parsed)
			.map(([key, value]) => `${key}: ${JSON.stringify(value)}`)
			.join('\n');
	} catch (e) {
		return args;
	}
}
</script>

<style scoped lang="scss">
@import "/dam_uni_frame/styles/dam_theme_common.scss";
@import "/static/css/iconfont.css";

/* 整体聊天容器，设置内边距 */
.chat-container {
	box-sizing: border-box;
	padding: 0 10px 0px;
}

/* 消息列表容器，使用 flex 布局 */
.message-list {
	flex: 1;
	display: flex;
	flex-direction: column;
	overflow-y: auto;
}

/* 公共消息泡泡样式 */
.message-bubble {
	display: flex;
	align-items: center;
	margin: 10px 0;
	border-radius: 15px;
	width: max-content;
	animation: slideIn 0.3s ease;
	line-height: 1.5;
}

/* 用户消息样式（靠右显示） */
.user {
	max-width: 90%;
	padding: 8px 15px 10px 15px;
	background: linear-gradient(135deg, #d2e6ff, #9acdff);
	color: #1b1b1b;
	margin-left: auto;
	border-radius: 18px 4px 18px 18px;
	box-shadow: 0 3px 10px rgba(60, 156, 255, 0.15);
	transition: all 0.3s ease;

	&:active {
		transform: scale(0.98);
	}
}

/* 助手消息样式（靠左显示） */
.assistant {
	max-width: 100%;
	margin-right: auto;
	transition: all 0.3s ease;

	.message-content {
		transition: all 0.3s ease;
	}

	&:active .message-content {
		transform: scale(0.98);
	}
}

/* 助手头像样式 */
.assistant-avatar {
	margin-right: 10px;
	display: flex;
	flex-direction: inherit;
	align-items: center;

	.left-icon {
		display: flex;
		justify-content: center;
		align-items: center;
		margin-left: 5px;
		width: 20px;
		height: 20px;

		.spinner-cycle {
			margin-left: 10px;
			animation: spin 0.5s linear infinite;
			font-size: 22px;
			color: gray;
		}
	}

}

/* 消息项布局 */
.message-item {
	display: flex;
	align-items: flex-start;
}

/* 消息内容区域，内含文本和流式加载动画 */
.message-content {
	display: flex;
	flex-direction: column;
	max-width: calc(100vw - 20px);

	.message-root {
		display: flex;
		flex-direction: column;
		justify-content: center;
		word-break: break-all;

		/* 思考状态显示样式 */
		.thinking-status {
			display: flex;
			align-items: center;
			margin-bottom: 8px;
			padding: 8px 12px;
			background-color: rgba(230, 244, 255, 0.7);
			border-radius: 8px;
			position: relative;

			.spinner-cycle {
				animation: spin 0.8s linear infinite;
				font-size: 18px;
				color: #2196F3;
				margin-right: 10px;
			}

			text {
				font-size: 14px;
				color: #2196F3;
				font-weight: 500;
			}

			.thinking-fade {
				position: absolute;
				bottom: 0;
				left: 0;
				width: 100%;
				height: 100%;
				background: linear-gradient(to bottom, transparent, transparent 70%, rgba(230, 244, 255, 0.3) 100%);
				pointer-events: none;
			}
		}

		.reasoning_content {
			margin-bottom: 8px;
			color: #83868b;
			font-size: 14px;
			display: flex;
			padding: 8px 5px 0px 10px;
			border-radius: 4px 18px 18px 18px;
			box-shadow: 0 3px 10px rgba(0, 0, 0, 0.05);
			background-color: #f5f7fa;

			.left {
				margin-right: 10px;
				background: gainsboro;
				width: 5px;
			}
		}

		.content {
			font-size: 16px;
			word-break: break-all;
		}

		.ass {
			padding: 10px 5px 10px 12px;
			border-radius: 4px 18px 18px 18px;
			box-shadow: 0 3px 10px rgba(0, 0, 0, 0.05);
			background-color: #f5f7fa;
		}

	}

	.bottom-but {
		margin: 6px 10px;
		icon {
			font-size: 20px;
			margin-right: 10px;
			color: #83868b;
		}
	}

}

/* 助手头像 logo 样式 */
.jz-logo {
	width: 40px;
	height: 40px;
	border-radius: 50%;
	border: 1px solid #3c9cff;
	background: linear-gradient(135deg, #ffffff, #f5f7fa);
	box-shadow: 0 3px 8px rgba(60, 156, 255, 0.2);
}

/* 滑入动画效果 */
@keyframes slideIn {
	from {
		opacity: 0;
		transform: translateY(10px);
	}

	to {
		opacity: 1;
		transform: translateY(0);
	}
}

@keyframes spin {
	from {
		transform: rotate(0deg);
	}

	to {
		transform: rotate(360deg);
	}
}

/* 工具调用卡片样式 */
.tool-calls {
	width: 100%;
	margin-top: 6px;
}

.tool-card {
	background-color: rgba(64, 158, 255, 0.08);
	border-radius: 8px;
	padding: 10px 12px 10px 10px;
	margin-bottom: 8px;
	transition: all 0.2s ease;

	&:hover {
		background-color: rgba(64, 158, 255, 0.12);
	}

	.tool-header {
		display: flex;
		align-items: center;

		.iconfont {
			font-size: 18px;
			color: #409eff;
			margin-right: 8px;
		}

		.tool-name {
			color: #409eff;
			font-size: 14px;
			font-weight: 500;
		}
	}

	.tool-args {
		background: rgba(255, 255, 255, 0.9);
		border-radius: 6px;
		margin-top: 8px;
		margin-bottom: 4px;
		padding: 10px 12px;
		box-shadow: 0 1px 5px rgba(0, 0, 0, 0.05);
		border-left: 2px solid #e6e6e6;

		.args-text {
			font-family: 'Consolas', monospace;
			font-size: 13px;
			color: #4a4a4a;
			white-space: pre-wrap;
			word-break: break-all;
			line-height: 1.6;
		}
	}
}
</style>